package service

import (
	"fmt"
	"regexp"
	"strings"

	"tool/model"
	"tool/utils"

	"gitee.com/xuesongtao/protoc-go-valid/log"
	"gitee.com/xuesongtao/protoc-go-valid/valid"
)

func Sql2Proto(req *model.Sql2ProtoReq) *model.RespData {
	log.Infof("Sql2Proto req: %+v", req)
	if err := valid.ValidateStruct(req); err != nil {
		log.Error("valid is failed, err: ", err)
		return model.GetResp("此语句不是建表语句", 1)
	}

	// 全部转小写
	reqData := strings.ToLower(strings.Trim(req.Data, " "))

	// 先判断下是否为建表语句, 如果不是就直接返回
	// CREATE TABLE
	if !strings.Contains(strings.ToLower(reqData[:13]), "create table") {
		return model.GetResp("此语句不是建表语句", 1)
	}

	lastIndex := len(reqData) - 1

	// 取左,右括号
	leftBracket := strings.Index(reqData, "(")
	rightBracket := strings.LastIndex(reqData, ")")
	// 判断下是否为最后一个 ")", 最后一个应该为 ")" 后有空格或者";"同时不能出现在引号中
	tmpSqlStr := reqData
	for {
		rightBracket = strings.LastIndex(tmpSqlStr, ")")
		if rightBracket < leftBracket || rightBracket+1 >= lastIndex {
			break
		}

		// 通过 ") "来判断最后一个, 同时不能出现在注释里
		nextVal := tmpSqlStr[rightBracket+1]
		toEndStr := tmpSqlStr[rightBracket:]
		if (nextVal == ' ' || nextVal == ';') && (strings.Contains(toEndStr, "'") || strings.Contains(toEndStr, "\"")) {
			break
		}
		tmpSqlStr = tmpSqlStr[:rightBracket]
	}

	// 开始生成 proto
	respBuf := new(strings.Builder)
	tableIndex := strings.Index(reqData, "table")
	tableName := strings.ReplaceAll(reqData[tableIndex+5:leftBracket-1], "`", "")
	log.Info("tab: ", tableName)
	// 生成 message xxxInfo {
	respBuf.WriteString(fmt.Sprintf("%s %sInfo {", utils.CodeKeyWordFont("message"), utils.SplitStr2Title(tableName, "_")))
	respBuf.WriteByte('\n')

	// 解析
	filedAttrs := strings.Split(reqData[leftBracket+1:rightBracket], ",\n")
	if len(filedAttrs) <= 1 {
		return model.GetResp("需要先格式化下再来哟!", 1)
	}
	for index, lineStr := range filedAttrs {
		// 行内容, 如: `hospital_id` int(11) not null comment '医院id'
		if index == 0 { // 第一个要处理下 \n
			lineStr = strings.TrimLeft(lineStr, "\n")
		}
		lineArr := strings.Split(strings.TrimLeft(lineStr, " "), " ")
		filedName := strings.ReplaceAll(lineArr[0], "`", "")
		filedName = strings.Trim(filedName, " ")
		if filedName == "primary" || filedName == "key" || filedName == "unique" {
			continue
		}
		filedType := model.GetProtoType(lineArr[1])
		filedNum := index + 1
		// message内容, 如: string hospital_id = 1; // 医院id
		respBuf.WriteString(fmt.Sprintf("  %s %s = %d;", utils.CodeKeyWordFont(filedType), filedName, filedNum))
		regexpCommentArr := regexp.MustCompile("comment ['|\"](.*)['|\"]").FindStringSubmatch(lineStr)
		// 处理注释
		if len(regexpCommentArr) >= 2 {
			respBuf.WriteString(" // " + regexpCommentArr[1])
		}
		respBuf.WriteByte('\n')
	}
	respBuf.WriteByte('}')
	return model.GetResp(respBuf.String())
}
